<?php

class HasManyAssociationDAO extends AssociationDAO
{

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/association/AssociationDAO#afterSave($client)
   */
  public function afterSave(&$client, $params = array())
  {
    $def = $this->getDefinition();

    $name = $def->getName();

    if (isset($client[$name])) {
      $pk = $def->getPrimaryKey();

      $id = $client[$pk];

      if (empty($id)) {
        throw new Exception('Cannot save associated data: primary key of source object not set');
      }

      $fk = $def->getForeignKey();

      $_client = array($pk => $id);

      $this->find($_client);

      $diff = sy_data_diff($_client[$name], $client[$name], $def->getTarget()->getPkName());

      $rep = Repository::getInstance($def->getTarget()->getName());

      foreach ($diff['delete'] as $row) {
        $rep->delete($row);
      }

      $client[$name] = array_merge($diff['create'], $diff['update']);

      $data = $client[$name];

      foreach ($data as &$row) {
        $row[$fk] = $client[$pk];
        $rep->save($row);
      }

      $client[$name] = $data;
    }
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/association/AssociationDAO#find($clients)
   */
  public function find(&$clients, $params = null)
  {
    $dao = DAO::getInstance();

    $def = $this->getDefinition();

    $name = $def->getName();
    $table = $def->getTarget()->getTable();
    $fk = $def->getForeignKey();
    $pk = $def->getPrimaryKey();
    $fields = Repository::collectFields($def->getTarget());

    $query = $dao->query();

    $params = (array)$params;
    if (isset($params['where'])) {
      $query->where($params['where']);
    }

    /**
     * single client
     */
    if (isset($clients[$pk])) {
      $id = $clients[$pk];

      $data = $query->from($table)->select($fields)->where("$fk = ?")->execute($id)->fetchAll();

      $clients[$name] = $data;
    }

    /**
     * collection of clients
     */
    else {
      $ids = array();
      foreach ($clients as $client) {
        $ids[$client[$pk]] = $client[$pk];
      }

      if (! empty($ids)) {
        $ids = implode(', ', array_map(array($dao, 'quote'), $ids));

        $data = $query->from($table)->select($fields)->where("$fk IN ($ids)")->execute()->fetchAll();

        foreach ($clients as & $client) {
          foreach ($data as $row) {
            if ($row[$fk] == $client[$pk]) {
              $client[$name][] = $row;
            }
          }

          if (! isset($client[$name]) && $def->isRequired()) {
            $client[$name] = array();
          }
        }
      }
    }
  }

}

?>